#include <iostream>
#include <pthread.h>
#include <string>
#include <unistd.h>
#include "Mutex.hpp"
// pthread_mutex_t glock = PTHREAD_MUTEX_INITIALIZER;
using namespace MutexModule;
class ThreadDate
{
public:
    ThreadDate(const std::string n, Mutex &lock)
        : name(n),
          lockp(&lock)
    {
    }
    ~ThreadDate() {}

    std::string name;
    Mutex *lockp;
};

int ticket = 1000;

void *routine(void *args)
{
    ThreadDate *td = static_cast<ThreadDate *>(args);
    while (true)
    {
        {
            MutexGuard guard(td->lockp);
            if (ticket > 0)
            {
                usleep(1000);
                printf("%s sells ticket:%d\n", td->name.c_str(), ticket);
                ticket--;
            }
            else
            {
                break;
            }
        }
    }
    return nullptr;
}
int main()
{
    Mutex lock;
    // pthread_mutex_init(&lock,nullptr);
    pthread_t tid1;
    pthread_t tid2;
    pthread_t tid3;
    pthread_t tid4;

    ThreadDate *td1 = new ThreadDate("thread 1", lock);
    pthread_create(&tid1, nullptr, routine, td1);

    ThreadDate *td2 = new ThreadDate("thread 2", lock);
    pthread_create(&tid2, nullptr, routine, td2);

    ThreadDate *td3 = new ThreadDate("thread 3", lock);
    pthread_create(&tid3, nullptr, routine, td3);

    ThreadDate *td4 = new ThreadDate("thread 4", lock);
    pthread_create(&tid4, nullptr, routine, td4);

    pthread_join(tid1, nullptr);
    pthread_join(tid2, nullptr);
    pthread_join(tid3, nullptr);
    pthread_join(tid4, nullptr);

    // pthread_mutex_destroy(&lock);

    return 0;
}

// void *routine(void *args)
// {
//     ThreadDate *td = static_cast<ThreadDate *>(args);
//     while (true)
//     {
//         // pthread_mutex_lock(&glock);
//         // pthread_mutex_lock(td->lockp);
//         // td->lockp->Lock();
//         MutexGuard guard(td->lockp);
//         if (ticket > 0)
//         {
//             usleep(1000);
//             printf("%s sells ticket:%d\n", td->name.c_str(), ticket);
//             ticket--;
//             // pthread_mutex_unlock(&glock);
//             // pthread_mutex_unlock(td->lockp);
//             // td->lockp->Unlock();
//         }
//         else
//         {
//             // pthread_mutex_unlock(&glock);
//             // pthread_mutex_unlock(td->lockp);
//             // td->lockp->Unlock();

//             break;
//         }
//     }
//     return nullptr;
// }